package com.yuncheng.spcyApi.utils;

import cn.hutool.core.date.DateUtil;
import com.itextpdf.text.DocumentException;
import com.yuncheng.spcyApi.config.SpcyMinioUtils;
import com.yuncheng.spcyApi.constant.common.BusinessConstant;
import com.yuncheng.spcyApi.constant.common.SpcyConstant;
import com.yuncheng.exception.BusinessException;
import net.coobird.thumbnailator.Thumbnails;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;
import utils.DateConversionUtils;
import utils.PdfUtils;
import utils.Util;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.Part;
import java.io.*;
import java.net.URLEncoder;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Date;
import java.util.UUID;

/**
 * 本地上传文件工具类
 */
@Component
public class LocalFileUploadUtils {
    private static final Logger log = LoggerFactory.getLogger(LocalFileUploadUtils.class);

    @Resource
    private BusinessConstant bussinessConstant;

    @Resource
    @Lazy
    private WordPdfUtils wordPdfUtils;

    @Resource
    @Lazy
    private SpcyMinioUtils spcyMinioUtils;

    /**
     * 是否启用本地上传(文件记录)
     * @return
     */
    public boolean isEnableMinioWjjlFile(){
        return bussinessConstant.IS_ENABLE_WJJL_MINIO;
    }

    /**
     * 是否启用本地上传（签名）
     * @return
     */
    public boolean isEnableMinioQmFile(){
        return bussinessConstant.isEnableUserQmMinio;
    }

    /**
     * 是否启用本地上传（文件模板）
     * @return
     */
    public boolean isEnableMinioWjmbFile(){
        return bussinessConstant.isEnableWjmbMinio;
    }

    /**
     * 是否启用本地上传(质量体系文件)
     * @return
     */
    public boolean isEnableMinioZltxwjFile(){
        return bussinessConstant.isEnableZltxwnjMinio;
    }

    /**
     * 是否启用本地上传(法规标准库)
     * @return
     */
    public boolean isEnableMinioFgbzkFile(){
        return bussinessConstant.isEnableFgbzkMinio;
    }

    /**
     * 是否启用本地上传(自定义文件)
     * @return
     */
    public boolean isEnableMinioZdyFile(){
        return false;
    }

    /** 获取系统文件存放根路径 */
    public String getSysRootUrl(){
        return bussinessConstant.UPLOAD_FILE_ROOT;
    }

    /** 获取申请事项文件-相对路径 */
    public String getSqsxWjjlRelativeUrl(String rootUrl){
        return "/"+SpcyConstant.WJJL_FILE_BASE_URL + rootUrl;
    }

    /** 获取申请事项文件-绝对路径 */
    public String getSqsxWjjlAbsUrl(String rootUrl){
        return bussinessConstant.YUNCEHNG_PATH_UPLOAD + rootUrl;
    }

    /** 获取文件模板相对路径 */
    public String getWjmbRelativeUrl(String rootUrl){
        return "/"+SpcyConstant.WJMB_FILE_BASE_URL + rootUrl;
    }

    /** 获取文件模板绝对路径 */
    public String getWjmbAbsUrl(String rootUrl){
        return bussinessConstant.UPLOAD_WJMB_PATH + rootUrl;
    }

    /**
     * 利用字节流复制
     * @param src
     * @param dest
     * @throws IOException
     */
    public void copyFile(String src,String dest) throws IOException{
        InputStream is = new BufferedInputStream(new FileInputStream(src));
        OutputStream os = new BufferedOutputStream(new FileOutputStream(dest));
        //文件拷贝u，-- 循环+读取+写出
        byte[] b = new byte[10];//缓冲大小
        int len = 0;//接收长度
        //读取文件
        while (-1!=(len = is.read(b))) {
            //读入多少，写出多少，直到读完为止。
            os.write(b,0,len);
        }
        //强制刷出数据
        os.flush();
        //关闭流，先开后关
        os.close();
        is.close();
    }

    // (文件记录) - 虚拟文件路径删除
    public void deleteLocalFileUrl(String xnUrl){
        this.deleteLocalFileUrl(xnUrl,true);
    }

    public void deleteLocalFileUrl(String xnUrl,boolean isLocal){
        if (this.isEnableMinioWjjlFile() && isLocal){
            spcyMinioUtils.remove(this.getSqsxWjjlRelativeUrl(xnUrl));
        }

        if (isLocal || !isLocal) {
            File file = new File(this.getSqsxWjjlAbsUrl(xnUrl));
            if (file.exists()) {
                file.delete();
            }
        }
    }

    // （文件模板）- 虚拟文件路径删除
    public void deleteLocalWjmbFileUrl(String xnUrl){
        if (this.isEnableMinioWjmbFile()) {
            spcyMinioUtils.remove(getWjmbRelativeUrl(xnUrl));
        }else {

            String fileUrl = getWjmbAbsUrl(xnUrl);
            File file = new File(fileUrl);
            if (file.exists()) {
                file.delete();

                if (bussinessConstant.isEnableWjmbMinio) {
                    spcyMinioUtils.remove(getWjmbRelativeUrl(xnUrl));
                }
            }
        }
    }

    // （自定义）- 全路径文件路径删除
    public void deleteLocalFileUrlByZltxwj(String xnUrl){
        if (isEnableMinioZltxwjFile()) {
            this.deleteLocalFileUrlByZdy(xnUrl, true);
        }else {
            this.deleteLocalFileUrlByZdy(xnUrl, false);
        }
    }

    // （自定义）- 全路径文件路径删除
    public void deleteLocalFileUrlByZdy(String xnUrl){
        this.deleteLocalFileUrlByZdy(xnUrl,false);
    }

    public void deleteLocalFileUrlByZdy(String xnUrl,boolean isMinio){
        if (this.isEnableMinioZdyFile()){
            spcyMinioUtils.remove(xnUrl);
        }else {
            if (isMinio){
                spcyMinioUtils.remove(xnUrl);
            }else {

                xnUrl = getZdyFileAbsUrl(xnUrl);
                File file = new File(xnUrl);
                if (file.exists()) {
                    file.delete();
                }
            }
        }
    }

    /** 删除本地文件-本地绝对路径 */
    public static void deleteAbsFile(File file){
        try {
            if (file.exists()) {
                file.delete();
            }
        }catch (Exception e){
            log.error("删除本地文件-本地绝对路径-失败!");
        }
    }

    public static void deleteAbsFile(String absUrl){
        deleteAbsFile(new File(absUrl));
    }

    // （文件模板）-真实文件路径下载
    public void getLocalWjmbFileURL(String fileNameUrl,String fileName,HttpServletResponse response){
        if (this.isEnableMinioWjmbFile()){
            spcyMinioUtils.download(getWjmbRelativeUrl(fileNameUrl),response);

        }else {

            fileNameUrl = getWjmbAbsUrl(fileNameUrl);
            try {
                // path是指想要下载的文件的路径
                File file = new File(fileNameUrl);
                // 获取文件名
                String filename = file.getName();
                // 获取文件后缀名
                String ext = filename.substring(filename.lastIndexOf(".") + 1).toLowerCase();
                // 将文件写入输入流
                FileInputStream fileInputStream = new FileInputStream(file);
                InputStream fis = new BufferedInputStream(fileInputStream);
                byte[] buffer = new byte[fis.available()];
                fis.read(buffer);
                fis.close();
                // 清空response
                response.reset();
                // 设置response的Header
           /* if (request.getHeader("User-Agent").toUpperCase().contains("MSIE") ||
                    request.getHeader("User-Agent").toUpperCase().contains("TRIDENT")
                    || request.getHeader("User-Agent").toUpperCase().contains("EDGE")) {
                name = java.net.URLEncoder.encode(name, "UTF-8");
            } else {
                //非IE浏览器的处理：
                name = new String(name.getBytes("UTF-8"), "ISO-8859-1");
            }*/
                response.setCharacterEncoding("UTF-8");
                response.addHeader("Access-Control-Allow-Origin", "*");
                response.addHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE");
                //Content-Disposition的作用：告知浏览器以何种方式显示响应返回的文件，用浏览器打开还是以附件的形式下载到本地保存
                //attachment表示以附件方式下载   inline表示在线打开   "Content-Disposition: inline; filename=文件名.mp3"
                // filename表示文件的默认名称，因为网络传输只支持URL编码的相关支付，因此需要将文件名URL编码后进行传输,前端收到后需要反编码才能获取到真正的名称
//            response.addHeader("Content-Disposition", "attachment;filename=".concat(String.valueOf(URLEncoder.encode(fileName, "UTF-8"))) + '.' + ext);
                response.addHeader("Content-Disposition", "attachment;filename=".concat(String.valueOf(URLEncoder.encode(fileName, "UTF-8"))));

                // 告知浏览器文件的大小
                response.addHeader("Content-Length", "" + file.length());
                OutputStream outputStream = new BufferedOutputStream(response.getOutputStream());
                response.setContentType("application/octet-stream;charset=UTF-8");
                outputStream.write(buffer);
                outputStream.flush();
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
    }

    // （文件记录）虚拟文件路径下载-二进制下载
    public void ejzLocalFileURl(String fileNameUrl,HttpServletResponse response){
        if (this.isEnableMinioWjjlFile()){
            spcyMinioUtils.download(this.getSqsxWjjlRelativeUrl(fileNameUrl), response);

        }else {

            File file = new File(this.getSqsxWjjlAbsUrl(fileNameUrl));

            this.ejzLocalFileByZdyFile(file, response);
        }
    }

    /**
     * 申请事项文件-水印文件下载
     * @param fileNameUrl 文件相对路径
     * @param wjhz 文件后缀
     * @param symc 水印名称
     * @param response
     */
    public void ejzSqsxFileURLSy(String fileNameUrl, String wjhz, String symc, HttpServletResponse response){
        String absPath = "";

        if (StringUtils.isBlank(wjhz)){
            wjhz = Util.getWjHz(fileNameUrl);
        }

        boolean isQtLxFile = false;
        if (this.isEnableMinioWjjlFile()) {

            if (wjhz.equals(".doc") || wjhz.equals(".docx") || wjhz.equals(".pdf")) {
                InputStream minioInput = spcyMinioUtils.getObject(this.getSqsxWjjlRelativeUrl(fileNameUrl));
                if (minioInput == null){
                    throw new BusinessException("文件流不存在！");
                }
                File file = this.asFile(minioInput, wjhz);
                absPath = file.getAbsolutePath();

            } else {
                isQtLxFile = true;
            }

        }else {
            absPath = this.getSqsxWjjlAbsUrl(fileNameUrl);

            File file = new File(absPath);
            if (!file.exists()) {
                throw new BusinessException("文件不存在！");
            }
        }

        if (isQtLxFile){
            if (this.isEnableMinioWjjlFile()) {
                spcyMinioUtils.download(this.getSqsxWjjlRelativeUrl(fileNameUrl), response);
            }else {
                this.ejzLocalFileByZdyFile(new File(this.getSqsxWjjlAbsUrl(fileNameUrl)), response);
            }

        }else {
            if (StringUtils.isBlank(symc)) {
                symc = BusinessConstant.FILE_SY_NAME;
            }
            this.ejzLocalFileSy(absPath, wjhz, symc, response);
        }
    }

    /**
     * 自定义本地文件orminio文件-水印文件下载
     * @param fileNameUrl 文件相对路径
     * @param wjhz 文件后缀
     * @param symc 水印名称
     * @param response
     */
    public void ejzZdyLocalFileUrlSy(String fileNameUrl, String wjhz, String symc, HttpServletResponse response){
        ejzZdyLocalOrMinioFileURLSy(fileNameUrl, wjhz, symc, false, response);
    }
    public void ejzZdyMinioFileUrlSy(String fileNameUrl, String wjhz, String symc, HttpServletResponse response){
        ejzZdyLocalOrMinioFileURLSy(fileNameUrl, wjhz, symc, true, response);
    }
    public void ejzZdyMinioFileUrlSy(String fileNameUrl, String wjhz, String symc, boolean isMinio, HttpServletResponse response){
        ejzZdyLocalOrMinioFileURLSy(fileNameUrl, wjhz, symc, isMinio, response);
    }
    private void ejzZdyLocalOrMinioFileURLSy(String fileNameUrl, String wjhz, String symc, boolean isMiinio, HttpServletResponse response){
        String absPath = "";

        if (StringUtils.isBlank(wjhz)){
            wjhz = Util.getWjHz(fileNameUrl);
        }

        boolean isQtLxFile = false;
        if (isMiinio) {

            if (wjhz.equals(".doc") || wjhz.equals(".docx") || wjhz.equals(".pdf")) {
                InputStream minioInput = spcyMinioUtils.getObject(fileNameUrl);
                if (minioInput == null){
                    throw new BusinessException("文件流不存在！");
                }
                File file = this.asFile(minioInput, wjhz);
                absPath = file.getAbsolutePath();

            } else {
                isQtLxFile = true;
            }

        }else {

            absPath = getZdyFileAbsUrl(fileNameUrl);

            File file = new File(absPath);
            if (!file.exists()) {
                throw new BusinessException("文件不存在！");
            }
        }

        if (isQtLxFile){
            if (isMiinio) {
                spcyMinioUtils.download(fileNameUrl, response);
            }else {
                this.ejzLocalFileByZdyFile(new File(this.getZdyFileAbsUrl(fileNameUrl)), response);
            }

        }else {
            if (StringUtils.isBlank(symc)) {
                symc = BusinessConstant.FILE_SY_NAME;
            }
            this.ejzLocalFileSy(absPath, wjhz, symc, response);
        }
    }

    /** 本地文件水印-水印下载
     * @param symc 水印名称
     * @param absPath 本地文件绝对路径
     * @param wjhz 文件后缀
     * */
    public void ejzLocalFileSy(String absPath, String wjhz, String symc, HttpServletResponse response){

        boolean isSy = true;
        String pdfUrl = bussinessConstant.TEMPORARY_UPLOAD_MKDIR_ROOT + "/" + SpcyConstant.TEMP_WJJL_CHILD_URL;

        if (wjhz.equals(".doc") || wjhz.equals(".docx")) {
            File dir = new File(pdfUrl);
            if (!dir.exists()) {
                dir.mkdirs();
            }
            String nowDate = DateConversionUtils.DateToYYYYMMDD(new Date());
            pdfUrl += "/" + nowDate + "-" + GetUuIdUtils.ReplaceUuId() + ".pdf";
            wordPdfUtils.wordToPdf(absPath, pdfUrl);

        } else if (wjhz.equals(".pdf")){
            pdfUrl = absPath;

        } else {
            isSy = false;
        }

        if (isSy) {
            try {
                PdfUtils.setWordMark(response.getOutputStream(), pdfUrl, symc, false);
            } catch (DocumentException e) {
                log.error("（文件记录）水印文件下载-【DocumentException】-出错-{}", e.getMessage());
            } catch (IOException e) {
                log.error("（文件记录）水印文件下载-【IOException】-出错-{}", e.getMessage());
            }
        }else {
            this.ejzLocalFileByZdyFile(new File(pdfUrl), response);
        }
    }

    // (文件模板)虚拟文件路径下载-二进制下载
    public void ejzLocalWjmbFileURl(String fileNameUrl,HttpServletResponse response){
        if (this.isEnableMinioWjmbFile()){
            spcyMinioUtils.download("/"+SpcyConstant.WJMB_FILE_BASE_URL+fileNameUrl,response);
        }else {

            log.info("文件模板路径： {}", fileNameUrl);
            String path = bussinessConstant.UPLOAD_WJMB_PATH + fileNameUrl;
            File file = new File(path);
            log.info("文件模板路径： {}", file.getAbsolutePath());
            this.ejzLocalFileByZdyFile(file, response);
        }
    }

    /** 获取用户签名绝对路径 */
    public String getUserQmAbsUrl(String rootUrl){
        return bussinessConstant.USER_QM_PATH + rootUrl;
    }

    /**
     * 获取用户签名相对路径
     * @param rootUrl
     */
    public static String getUserQmRelaviteUrl(String rootUrl){
        return "/"+SpcyConstant.USERQM_FILE_BASE_URL + rootUrl;
    }

    // (用户签名)虚拟文件路径下载-二进制下载
    public void ejzLocalQmFileURl(String fileNameUrl,HttpServletResponse response){
        if (this.isEnableMinioQmFile()){
            spcyMinioUtils.download(this.getUserQmRelaviteUrl(fileNameUrl), response);
        }else {
            File file = new File(this.getUserQmAbsUrl(fileNameUrl));

            this.ejzLocalFileByZdyFile(file, response);
        }
    }

    // （质量体系文件）虚拟文件路径下载-二进制下载
    public void ejzLocalFileURlByZltxwj(String fileNameUrl,HttpServletResponse response){
        if (isEnableMinioZltxwjFile()) {
            this.ejzLocalFileURlByZdy(fileNameUrl, true, response);
        }else {
            this.ejzLocalFileURlByZdy(fileNameUrl, false, response);
        }
    }

    // （法规标准库）虚拟文件路径下载-二进制下载
    public void ejzLocalFileURlByFgbzk(String fileNameUrl,HttpServletResponse response){
        if (isEnableMinioFgbzkFile()) {
            this.ejzLocalFileURlByZdy(fileNameUrl, true, response);
        }else {
            this.ejzLocalFileURlByZdy(fileNameUrl, false, response);
        }
    }

    // （自定义）虚拟文件路径下载-二进制下载
    public void ejzLocalFileURlByZdy(String fileNameUrl,HttpServletResponse response){
        this.ejzLocalFileURlByZdy(fileNameUrl, false,response);
    }

    /** 获取自定义文件绝对路径-根据相对路径 */
    public String getZdyFileAbsUrl(String relUrl){
        return bussinessConstant.UPLOAD_FILE_ROOT + relUrl;
    }

    /** 自定义二进制文件下载
     * @param isMinio 是否启用minio
     * */
    public void ejzLocalFileURlByZdy(String fileNameUrl,boolean isMinio,HttpServletResponse response){
        if (this.isEnableMinioZdyFile()){
            spcyMinioUtils.download(fileNameUrl,response);
        }else {
            if (isMinio){
                spcyMinioUtils.download(fileNameUrl,response);
            }else {

                String path = getZdyFileAbsUrl(fileNameUrl);
                File file = new File(path);

                this.ejzLocalFileByZdyFile(file, response);
            }
        }
    }

    /**
     * 文档转pdf-并下载
     * @param wordUrl 文档绝对路径
     * */
    public void ejzWordConvertPdfDownFile(String wordUrl, HttpServletResponse response) throws IOException {
        if (StringUtils.isBlank(wordUrl)){
            response.setContentType("text/html");
            response.setCharacterEncoding("UTF-8");
            PrintWriter writer = response.getWriter();
            writer.println("没有相关文件模版！");
            writer.close(); // 不要忘记关闭PrintWriter
            return;
        }

        String destPdfUrl = this.getTempFileRootUrl() + "/" + GetUuIdUtils.NotReplaceUuId() + ".pdf";

        WordPdfUtils.wordToPdf(wordUrl, destPdfUrl);

        this.ejzLocalFileByZdyFile(new File(destPdfUrl), response);
    }

    // 自定义下载本地文件
    public void ejzLocalFileByZdyFile(File file,HttpServletResponse response){
        if (!file.exists()) {
            log.error("文件已删除或不存在");
            return;
        }
        InputStream in = null;
        OutputStream os = null;
        try {
            String wjhz = Util.getWjHz(file.getName());
            String contentType = Util.getContenTypeByWjhz(wjhz);
            response.setContentType(contentType); // 设置返回内容格式
            response.setCharacterEncoding("UTF-8");
            in = new FileInputStream(file); //用该文件创建一个输入流
            os = response.getOutputStream(); //创建输出流
            byte[] b = new byte[1024];
            while (in.read(b) != -1) {
                os.write(b);
            }
            in.close();
            os.flush();
            os.close();
        } catch (Exception e) {
            try {
                if (null != in) in.close();
            } catch (IOException e1) {
                log.error("{}: 自定义下载本地文件【IOException】e1: {}", file.getAbsoluteFile(), e1);
            }
            try {
                if (null != os) os.close();
            } catch (IOException e2) {
                log.error("{}: 自定义下载本地文件【IOException】e2: {}", file.getAbsoluteFile(), e2);
            }
        }
    }

    // 二进制文件保存
    public void uploadEjzFile(InputStream inputStream,String uploadUrl){
        File targetFile = new File(uploadUrl);
        try {
            FileUtils.copyInputStreamToFile(inputStream, targetFile);
        } catch (IOException e) {
            log.error("二进制文件上传失败: {}",e.getMessage());
        }
    }

    /**
     * 上传本地文件，自定义文件名(文件记录)
     * @param file 上传的文件
     * @param fileName 自定义文件名
     * @return
     */
    public File uploadLocalFile(MultipartFile file, String fileName){
        String originalFilename = file.getOriginalFilename();
        String newFileName = fileName + originalFilename.substring(originalFilename.lastIndexOf("."));
        File uploadFile = uploadExcelFile(file, newFileName);
        return uploadFile;
    }


    /**
     * 上传自定义目录, 文件路径的文件 (质量体系文件)
     * @param fileName 包含文件后缀
     * @param baseUrl 保存的文件目录 (第一字符不需要带斜杠（/）)
     */
    public File uploadZltxwjFile(MultipartFile file, String fileName, String baseUrl){
        if (isEnableMinioZltxwjFile()) {
            return this.uploadZdyFile(file, fileName, baseUrl, true);
        }else {
            return this.uploadZdyFile(file, fileName, baseUrl, false);
        }
    }

    /**
     * 上传自定义目录, 文件路径的文件 (法规标准库)
     * @param fileName 包含文件后缀
     * @param baseUrl 保存的文件目录 (第一字符不需要带斜杠（/）)
     */
    public File uploadFgbzkFile(MultipartFile file, String fileName, String baseUrl){
        if (isEnableMinioFgbzkFile()) {
            return this.uploadZdyFile(file, fileName, baseUrl, true);
        }else {
            return this.uploadZdyFile(file, fileName, baseUrl, false);
        }
    }

    /**
     * 上传自定义目录, 文件路径的文件
     * @param fileName 包含文件后缀
     * @param baseUrl 保存的文件目录 (第一字符不需要带斜杠（/）)
     */
    public File uploadZdyFile(MultipartFile file, String fileName, String baseUrl){
        return this.uploadZdyFile(file, fileName, baseUrl,false);
    }

    /**
     * 上传文件
     * @param file 文件流实体
     * @param fileName 文件名称+后缀
     * @param baseUrl 存储目录 (xxx/xxx)
     * @param isMinio
     * @return
     */
    public File uploadZdyFile(MultipartFile file, String fileName, String baseUrl,boolean isMinio){
        //获取绝对路径
        String newDir = "";
        if (StringUtils.isNotBlank(baseUrl)) {
            newDir = "/" + baseUrl;
        }else {
            String nowDay = DateConversionUtils.DateToMonthTwo(new Date()); // 获取当前日期 yyyy-MM-dd
            newDir = "/" + nowDay;
        }

        if (this.isEnableMinioZdyFile()){
            spcyMinioUtils.uploadFile(file,newDir+"/"+fileName);

            return null;
        }else {
            if (isMinio){
                spcyMinioUtils.uploadFile(file,newDir+"/"+fileName);
                return null;
            }else {

                File dir = new File(bussinessConstant.UPLOAD_FILE_ROOT + newDir);
                if (!dir.exists()) {
                    dir.mkdirs();
                }

                String filePath = new File(bussinessConstant.UPLOAD_FILE_ROOT + newDir).getAbsolutePath();
                //获取文件上传名称
                File fileUpload = new File(filePath, fileName);
                if (fileUpload.exists()) {
                    fileUpload.delete();
                }

                try {
                    //上传文件
                    file.transferTo(fileUpload);
                } catch (IOException e) {
                    e.printStackTrace();
                }
                return fileUpload;
            }
        }
    }

    /**
     * 上传本地文件，自定义文件名(文件记录)
     * @param file 上传的文件
     * @param fileName 自定义文件名 (不带后缀)
     * @return
     */
    public File uploadOnlineFile(MultipartFile file, String fileName,String fileType){
        String newFileName = fileName + fileType;
        File uploadFile = uploadExcelFile(file, newFileName);
        return uploadFile;
    }

    /**
     * 上传文件 功能(文件记录库上传)
     * @param file 上传的文件
     * @param fileName 上传文件的文件名 (带后缀)
     * @return
     */
    public File uploadExcelFile(MultipartFile file,String fileName){
        //获取绝对路径
        String nowDay = DateConversionUtils.DateToMonthTwo(new Date()); // 获取当前日期 yyyy-MM-dd
        String newDir = "/"+nowDay;

        if (this.isEnableMinioWjjlFile()){
            spcyMinioUtils.uploadFile(file,this.getSqsxWjjlRelativeUrl(newDir + "/" + fileName));

            return null;
        }else {

            File dir = new File(this.getSqsxWjjlAbsUrl(newDir));
            if (!dir.exists()) {
                dir.mkdirs();
            }

            String filePath = new File(this.getSqsxWjjlAbsUrl(newDir)).getAbsolutePath();
            //获取文件上传名称
            File fileUpload = new File(filePath, fileName);
            if (fileUpload.exists()) {
                fileUpload.delete();
            }

            try {
                //上传文件
                file.transferTo(fileUpload);
            } catch (IOException e) {
                e.printStackTrace();
            }
            return fileUpload;

        }
    }

    /**
     * 上传文件 功能(文件记录库上传)
     * @param file 上传的文件
     * @param wjml 文件目录 (首字母不带/)
     * @param fileName 上传文件的文件名(带后缀)
     * @return
     */
    public String uploadSqsxFile(MultipartFile file,String wjml,String fileName){
        if (StringUtils.isBlank(wjml)){
            String nowDay = DateConversionUtils.DateToMonthTwo(new Date()); // 获取当前日期 yyyy-MM-dd
            wjml = "/" + nowDay;
        }else {
            wjml = "/" + wjml;
        }

        if (this.isEnableMinioWjjlFile()){
            if (spcyMinioUtils.uploadFile(file, this.getSqsxWjjlRelativeUrl(wjml + "/" + fileName)) != null){
                return "true";
            }
        }else {

            File dir = new File(this.getSqsxWjjlAbsUrl(wjml));
            if (!dir.exists()) {
                dir.mkdirs();
            }

            String filePath = new File(this.getSqsxWjjlAbsUrl(wjml)).getAbsolutePath();
            //获取文件上传名称
            File fileUpload = new File(filePath, fileName);
            if (fileUpload.exists()) {
                fileUpload.delete();
            }

            try {
                //上传文件
                file.transferTo(fileUpload);
            } catch (IOException e) {
                e.printStackTrace();
            }
            return fileUpload.getAbsolutePath();
        }
        return null;
    }

    /**
     * 上传文件 功能(上传临时文件)
     * @param file 上传的文件
     * @param fileName 上传文件的文件名
     * @return
     */
    public File uploadDempFile(MultipartFile file,String fileName){
        //获取绝对路径
        String nowDay = DateUtil.today(); // 获取当前日期 yyyy-MM-dd
        String newDir = "/"+nowDay;

        File dir = new File(this.getTempFileRootUrl() + newDir);
        if (!dir.exists()) {
            dir.mkdirs();
        }
        String filePath = new File(this.getTempFileRootUrl() + newDir).getAbsolutePath();
        //获取文件上传名称
        File fileUpload = new File(filePath, fileName);
        if (fileUpload.exists()) {
            fileUpload.delete();
        }

        try {
            //上传文件
            file.transferTo(fileUpload);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return fileUpload;

    }

    /**
     * 上传文件 功能(上传临时文件)
     * @param part 上传的文件
     * @param fileName 上传文件的文件名
     * @return
     */
    public File uploadDempFile(Part part, String fileName){
        // 将文件保存到服务器
        try {
            Files.copy(part.getInputStream(), Paths.get(this.getTempFileRootUrl() + "/" + fileName));
            return new File(this.getTempFileRootUrl() + "/" + fileName);
        } catch (IOException e) {
            // 处理异常，例如记录日志或抛出运行时异常
            log.error("上传临时文件-Part错误：{}", e.getMessage());
            return null;
        }
    }

    /**
     * 上传本地文件，自定义文件名(文件模板)
     * @param file 上传的文件
     * @param fileName 自定义文件名（不带后缀）
     * @param baseUrl 存放目录 (首位不带 /)
     * @return
     */
    public File uploadLocalWjmbFile(MultipartFile file, String fileName, String baseUrl){
        String originalFilename = file.getOriginalFilename();
        String newFileName = fileName + originalFilename.substring(originalFilename.lastIndexOf("."));
        File uploadFile = uploadWjmbFile(file, newFileName, baseUrl);
        return uploadFile;
    }

    /**
     * 上传文件 功能 (文件模板)
     * @param file 上传的文件
     * @param fileName 上传文件的文件名 （带文件后缀）
     * @param baseUrl 存放目录 (首位不带 /)
     * @return
     */
    public File uploadWjmbFile(MultipartFile file, String fileName, String baseUrl){

        //获取绝对路径
        String newDir = "";
        if (StringUtils.isNotBlank(baseUrl)){
            newDir = "/" + baseUrl;
        }else {
            newDir = "/" + DateConversionUtils.DateToMonthTwo(new Date()); // 获取当前年月
        }

        if (this.isEnableMinioWjmbFile()){
            spcyMinioUtils.uploadFile(file, getWjmbRelativeUrl(newDir+"/"+fileName));

            return null;
        }else {

            File dir = new File(getWjmbAbsUrl(newDir));
            if (!dir.exists()) {
                dir.mkdirs();
            }

            String filePath = new File(getWjmbAbsUrl(newDir)).getAbsolutePath();
            //获取文件上传名称
            File fileUpload = new File(filePath, fileName);
            if (fileUpload.exists()) {
                fileUpload.delete();
            }

            try {
                //上传文件
                file.transferTo(fileUpload);
            } catch (IOException e) {
                e.printStackTrace();
            }

            if (bussinessConstant.isEnableWjmbMinio) {
                spcyMinioUtils.uploadFile(file, getWjmbRelativeUrl(newDir+"/"+fileName));
            }

            return fileUpload;
        }
    }

    /**
     * 上传文件 功能 (签名)
     * @param file 上传的文件
     * @param fileName 上传文件的文件名
     * @param ml 目录
     * @return
     */
    public File uploadUserQmFile(MultipartFile file,String fileName,String ml){

        if (this.isEnableMinioQmFile()){
            spcyMinioUtils.uploadFile(file,"/"+SpcyConstant.USERQM_FILE_BASE_URL+"/"+ml+"/"+fileName);

            return null;
        }else {

            //获取绝对路径
            File dir = new File(bussinessConstant.USER_QM_PATH+"/"+ml);
            if (!dir.exists()) {
                dir.mkdirs();
            }
            String filePath = new File(bussinessConstant.USER_QM_PATH+"/"+ml).getAbsolutePath();
            //获取文件上传名称
            File fileUpload = new File(filePath, fileName);
            if (fileUpload.exists()) {
                fileUpload.delete();
            }

            try {
                //上传文件
                file.transferTo(fileUpload);
            } catch (IOException e) {
                e.printStackTrace();
            }
            return fileUpload;
        }
    }

    /**
     * 删除文件-（签名）
     * @param xnUrl
     */
    public void deleteLocalQmFile(String xnUrl){
        xnUrl = getUserQmRelaviteUrl(xnUrl);
        if (this.isEnableMinioQmFile()){
            spcyMinioUtils.remove(xnUrl);
        }else {
            xnUrl = getZdyFileAbsUrl(xnUrl);
            File file = new File(xnUrl);
            if (file.exists()) {
                file.delete();
            }
        }
    }

    /** 获取临时文件存放根路径 */
    public String getTempFileRootUrl(){
        return bussinessConstant.TEMPORARY_UPLOAD_MKDIR_ROOT + "/" + SpcyConstant.TEMP_WJJL_CHILD_URL;
    }

    /**
     * 将文件流-转为File(生成临时文件 D:/upFiles/test/temp,默认文件以 TEMP 开头)
     * @param inputStream 文件流
     * @param wjhz 文件后缀
     * @return
     * @throws IOException
     */
    public File asFile(InputStream inputStream,String wjhz){
        File tmp = null;

        try {
            tmp = File.createTempFile("TEMP", wjhz, new File(this.getTempFileRootUrl()));
        } catch (IOException e) {
            log.error("将文件流-转为File失败【IOException】：{}",e.getMessage());
        }
        OutputStream os = null;
        try {
            os = new FileOutputStream(tmp);
            int bytesRead = 0;
            byte[] buffer = new byte[8192];
            while ((bytesRead = inputStream.read(buffer, 0, 8192)) != -1) {
                os.write(buffer, 0, bytesRead);
            }
            inputStream.close();
            os.close();
        } catch (IOException e) {
            log.error("将文件流-转为File失败【IOException】：{}",e.getMessage());
        }

        return tmp;
    }

    /**
     * 删除文件夹-临时文件
     * @param dir 文件夹
     */
    public static void deleteDirFile(File dir){
        try {
            FileUtils.cleanDirectory(dir);
        } catch (IOException e) {
            log.error("【IOException】出错-{}",e.getMessage());
        }
    }

    /**
     * 将minio文件转为本地文件
     * @param relativeUrl 相对路径
     * @param fwjlx 文件后缀
     */
    public File convertMinioToFile(String relativeUrl, String fwjlx){
        if (StringUtils.isBlank(fwjlx)){
            fwjlx = Util.getWjHz(relativeUrl);
        }
        InputStream minioInput = spcyMinioUtils.getObject(relativeUrl);
        if (minioInput == null){
//            throw new BusinessException("文件流不存在！");
            log.error("文件流不存在！路径：{}", relativeUrl);
            return null;
        }
        return this.asFile(minioInput, fwjlx);
    }

    /**
     * 压缩并上传图片
     * */
    public File compressImage(MultipartFile file) {
        String uploadPath = this.getTempFileRootUrl() + "/ystp";
        File updateFile = new File(uploadPath);
        if (!updateFile.exists()){
            updateFile.mkdir();
        }

        try {
            String wjHz = Util.getWjHz(file.getOriginalFilename());
            String outputFormat = Util.getExtension(wjHz);
            String random = UUID.randomUUID().toString();
            Thumbnails.of(file.getInputStream())
                    .scale(0.8f)
                    .outputFormat(outputFormat)
                    .outputQuality(0.5)
                    .toFile(uploadPath + random);

            return new File(uploadPath + random + wjHz);
        } catch (IOException e) {
            log.error("压缩并上传图片失败：{}", e.getMessage());
        }

        return null;
    }

    /**
     * 压缩并上传图片
     * */
    public File compressImage(File file) {
        String uploadPath = this.getTempFileRootUrl() + "/ystp";
        File updateFile = new File(uploadPath);
        if (!updateFile.exists()){
            updateFile.mkdir();
        }

        try {
            String wjHz = Util.getWjHz(file.getName());
            String outputFormat = Util.getExtension(wjHz);
            String random = UUID.randomUUID().toString();
            Thumbnails.of(new FileInputStream(file))
                    .scale(0.8f)
                    .outputFormat(outputFormat)
                    .outputQuality(0.5)
                    .toFile(uploadPath + random);

            return new File(uploadPath + random + wjHz);
        } catch (IOException e) {
            log.error("压缩并上传图片失败：{}", e.getMessage());
        }

        return null;
    }
}
